﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using FIFP.Common;
using FIFP.DashBoard.Model;
using System.Collections.ObjectModel;
using System.ComponentModel;
using FIFP.DashBoard.Helper;
using Telerik.Windows.Controls;
using System.Collections.Generic;
using Telerik.Windows.Controls.ScheduleView;
using FIFP.DashBoard.Converters;
using System.Collections;
using System.Linq;

namespace FIFP.DashBoard.ViewModel
{
    public class OptMngVM : ViewModelCore
    {
        #region Variables
        private List<FIFPAppointment> lsdActivities;
        private List<FIFPAppointment> optimizedPlans;
        private ObservableCollection<FIFPAppointment> linkedShutdownList;
        private ObservableCollection<FIFPAppointment> filteredLinkedShutdownList;
        public event EventHandler<CustomEventArgs<AppointmentGroup>> OnAppointmentDataCompleted;

        private List<FIFPAppointment> activityListWithSelectedUnit;
        private ObservableCollection<FIFPAppointment> filteredActivityListWithSelectedUnit;
        #endregion

        #region Properties

        private ObservableCollection<Unit> filteredLSDLocations;
        public ObservableCollection<Unit> FilteredLSDLocations
        {
            get { return filteredLSDLocations; }
            set { SetPropertyValue(() => FilteredLSDLocations, value, val => filteredLSDLocations = val); }
        }

        private List<Unit> linkedShutdownLocations = new List<Unit>();
        public List<Unit> LinkedShutdownLocations
        {
            get { return linkedShutdownLocations; }
            set { SetPropertyValue(() => LinkedShutdownLocations, value, val => linkedShutdownLocations = val); }
        }

        private Unit selectedLSDLocation;
        public Unit SelectedLSDLocation
        {
            get { return selectedLSDLocation; }
            set { SetPropertyValue(() => SelectedLSDLocation, value, val => selectedLSDLocation = val); }
        }

        public List<FIFPAppointment> LsdActivities
        {
            get { return lsdActivities; }
            set { SetPropertyValue(() => LsdActivities, value, val => lsdActivities = val); }
        }



        public ObservableCollection<FIFPAppointment> LinkedShutdownList
        {
            get { return linkedShutdownList; }
            set { SetPropertyValue(() => LinkedShutdownList, value, val => linkedShutdownList = val); }
        }

        public ObservableCollection<FIFPAppointment> FilteredLinkedShutdownList
        {
            get { return filteredLinkedShutdownList; }
            set { SetPropertyValue(() => FilteredLinkedShutdownList, value, val => filteredLinkedShutdownList = val); }
        }

        public List<FIFPAppointment> OptimizedPlans
        {
            get { return optimizedPlans; }
            set { SetPropertyValue(() => OptimizedPlans, value, val => optimizedPlans = val); }
        }


        private FIFPAppointment selectedActivity;
        public FIFPAppointment SelectedActivity
        {
            get { return selectedActivity; }
            set { SetPropertyValue(() => SelectedActivity, value, val => selectedActivity = val); }
        }

        private FIFPAppointment modifiedSelectedActivity;
        public FIFPAppointment ModifiedSelectedActivity
        {
            get { return modifiedSelectedActivity; }
            set { SetPropertyValue(() => ModifiedSelectedActivity, value, val => modifiedSelectedActivity = val); }
        }

        public List<FIFPAppointment> ActivityListWithSelectedUnit
        {
            get { return activityListWithSelectedUnit; }
            set { SetPropertyValue(() => ActivityListWithSelectedUnit, value, val => activityListWithSelectedUnit = val); }
        }

        public ObservableCollection<FIFPAppointment> FilteredActivityListWithSelectedUnit
        {
            get { return filteredActivityListWithSelectedUnit; }
            set { SetPropertyValue(() => FilteredActivityListWithSelectedUnit, value, val => filteredActivityListWithSelectedUnit = val); }
        }
        private ObservableCollection<FIFPAppointment> optimizedActivityList = new ObservableCollection<FIFPAppointment>();
        public ObservableCollection<FIFPAppointment> OptimizedActivityList
        {
            get { return optimizedActivityList; }
            set { SetPropertyValue(() => OptimizedActivityList, value, val => optimizedActivityList = val); }
        }


        private List<Unit> treeViewUnitList = new List<Unit>();
        public List<Unit> TreeViewUnitList
        {
            get { return treeViewUnitList; }
            set { SetPropertyValue(() => TreeViewUnitList, value, val => treeViewUnitList = val); }
        }

        private List<Unit> unitList = new List<Unit>();
        public List<Unit> UnitList
        {
            get { return unitList; }
            set { SetPropertyValue(() => UnitList, value, val => unitList = val); }
        }

        private Grid treeViewGrid;
        public Grid TreeViewGrid
        {
            get { return treeViewGrid; }
            set { SetPropertyValue(() => TreeViewGrid, value, val => treeViewGrid = val); }
        }


        private List<int> occpRadialUnitIds = new List<int>();
        public List<int> OccpRadialUnitIds
        {
            get { return occpRadialUnitIds; }
            set { SetPropertyValue(() => OccpRadialUnitIds, value, val => occpRadialUnitIds = val); }
        }

        private bool isNodeExists = false;
        public bool IsNodeExists
        {
            get { return isNodeExists; }
            set { SetPropertyValue(() => IsNodeExists, value, val => isNodeExists = val); }
        }
        private List<int> towerChildUnitList = new List<int>();
        public List<int> TowerChildUnitList
        {
            get { return towerChildUnitList; }
            set { SetPropertyValue(() => TowerChildUnitList, value, val => towerChildUnitList = val); }
        }

        private List<FIFPAppointment> scheduleViewAppointments = new List<FIFPAppointment>();
        public List<FIFPAppointment> ScheduleViewAppointments
        {
            get { return scheduleViewAppointments; }
            set { SetPropertyValue(() => ScheduleViewAppointments, value, val => scheduleViewAppointments = val); }
        }
        #endregion

        #region Commands


        private ICommand _ActivitySelectChanged;
        public ICommand ActivitySelectChanged
        {
            get
            {
                return _ActivitySelectChanged ??
                        (_ActivitySelectChanged = new RelayCommand<DataGrid>(ActivityDatagridSelectionChange));
            }
        }

        private ICommand _ModifiedActivitySelectChanged;
        public ICommand ModifiedActivitySelectChanged
        {
            get
            {
                return _ModifiedActivitySelectChanged ??
                        (_ModifiedActivitySelectChanged = new RelayCommand<DataGrid>(ModifiedActivityDatagridSelectionChange));
            }
        }



        private ICommand _LSDLocationSelectionChanged;
        public ICommand LSDLocationSelectionChanged
        {
            get
            {
                return _LSDLocationSelectionChanged ??
                        (_LSDLocationSelectionChanged = new RelayCommand<DataGrid>(LSDLocationGridSelectionChange));
            }
        }
        private ICommand _TreeviewGridLoaded;
        public ICommand TreeviewGridLoaded
        {
            get
            {
                return _TreeviewGridLoaded ??
                        (_TreeviewGridLoaded = new RelayCommand<Grid>(LoadTreeviewGrid));
            }
        }
        #endregion

        #region Constructor
        public OptMngVM()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                filteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>();
                ServiceLocator.Get<MainPageVM>().OnOptimizationClick += new EventHandler(OptMngVM_OnOptimizationClick);
            }
        }

        #endregion

        #region Reset
        public void Reset()
        {
            LinkedShutdownLocations = new List<Unit>(); 
            FilteredLSDLocations = new ObservableCollection<Unit>();
            FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>();
            OptimizedActivityList = new ObservableCollection<FIFPAppointment>();
            FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>();
            SelectedActivity = ModifiedSelectedActivity = null;
            if (TreeViewGrid != null && TreeViewGrid.Children.Count > 0)
                TreeViewGrid.Children.Clear();
        }

        public void ResetFromFilter()
        {
            FilteredLSDLocations = new ObservableCollection<Unit>();
            FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>();
            OptimizedActivityList = new ObservableCollection<FIFPAppointment>();
            FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>();
            SelectedActivity = ModifiedSelectedActivity = null;
            if (TreeViewGrid != null && TreeViewGrid.Children.Count > 0)
                TreeViewGrid.Children.Clear();
        }
        #endregion

        private void LoadUnitTypeFacilityList()
        {
            List<FilterData> unitTypeList = new List<FilterData>(ServiceLocator.Get<FilterVM>().UnitTypeList);
            unitTypeList.ForEach(s => { s.ItemVisibility = (s.FilterTypeName == FIFPConstants.UNITTYPE_STRING) ? Visibility.Collapsed : Visibility.Visible; });
            ServiceLocator.Get<FilterVM>().UnitTypeList = new ObservableCollection<FilterData>(unitTypeList);

            List<FilterData> facilityList = new List<FilterData>(ServiceLocator.Get<FilterVM>().FacilityList);
            facilityList.ForEach(s => { s.ItemVisibility = (s.FilterTypeName == FIFPConstants.UNITTYPE_PLATFORM) ? Visibility.Visible : Visibility.Collapsed; });
            ServiceLocator.Get<FilterVM>().FacilityList = new ObservableCollection<FilterData>(facilityList);
        }

        #region Get the original plans from Import UI while we click linked shutdown button from MainPage
        void OptMngVM_OnOptimizationClick(object sender, EventArgs e)
        {
            //LoadUnitTypeFacilityList();
            ServiceLocator.Get<FilterVM>().IsDivisionEnabled = false;
            LinkedShutdownLocations = new List<Unit>(); //Retailn the previous state
            ServiceLocator.Get<AppointmentVM>().RadScheduleViewDragDropBehavior = new OptimizationScheduleDragDropBehavior();
            //OptimizedPlans = ServiceLocator.Get<ShutdownMngVM>().ShutdownPlans;
            OptimizedPlans = ServiceLocator.Get<ImportVM>().ImportPlans.OrderBy(s => s.nIndex).ToList<FIFPAppointment>();
            //OptimizedPlans = (from item in ServiceLocator.Get<ImportVM>().ScenarioPlans
            //                  where (item.Start >= ServiceLocator.Get<FilterVM>().StartDate && item.End <= ServiceLocator.Get<FilterVM>().EndDate)
            //                  orderby item.nIndex ascending
            //                  select item).ToList<FIFPAppointment>();
            OptimizedPlans.ForEach(s => { s.ActivityLevel = 1; });//Undo only page level
            //FilteredLSDLocations = ServiceLocator.Get<ShutdownMngVM>().FilteredLSDLocations;
            UnitList = ServiceLocator.Get<ImportVM>().UnitList;
            GetOCCPRadialUnits();

            //if (LinkedShutdownLocations.Count == 0)
            {
                foreach (Unit unit in UnitList)
                {
                    unit.UnitNameTextColor = (unit.FluidType == FIFPConstants.FLUIDTYPE_OIL) ? new SolidColorBrush(new Color() { R = 0xFF, G = 0x59, B = 0x59, A = 0xFF }) : (unit.FluidType == FIFPConstants.FLUIDTYPE_WATER) ? new SolidColorBrush(new Color() { R = 0x4B, G = 0xAC, B = 0xC6, A = 0xFF }) : (unit.FluidType == FIFPConstants.FLUIDTYPE_GAS) ? new SolidColorBrush(new Color() { R = 0x93, G = 0xA8, B = 0x2A, A = 0xFF }) : (unit.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD) ? new SolidColorBrush(new Color() { R = 0x2E, G = 0x2E, B = 0x2E, A = 0xFF }) : new SolidColorBrush(new Color() { R = 0x80, G = 0x0D, B = 0x54, A = 0xFF });
                }

                if (OptimizedPlans != null && OptimizedPlans.Count > 0)
                {
                    foreach (FIFPAppointment activity in OptimizedPlans)
                    {

                        //Filter lsd plans according to the selection of selected location fluid type and it is applicable for pipelines and radials
                        if ((activity.UnitName != FIFPConstants.UNITTYPE_MOL && activity.UnitName != FIFPConstants.UNITTYPE_BYPASS_MOL && activity.UnitType == FIFPConstants.UNITTYPE_PIPELINE) || activity.UnitType == FIFPConstants.UNITTYPE_RADIAL)
                        {
                            if (activity.FluidType == FIFPConstants.FLUIDTYPE_OIL)
                                activity.LsdPlans = activity.LsdPlans.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_OIL || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<FIFPAppointment>();
                            else if (activity.FluidType == FIFPConstants.FLUIDTYPE_WATER)
                                activity.LsdPlans = activity.LsdPlans.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_WATER || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<FIFPAppointment>();
                            else if (activity.FluidType == FIFPConstants.FLUIDTYPE_GAS)
                                activity.LsdPlans = activity.LsdPlans.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_GAS || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<FIFPAppointment>();
                        }

                        activity.LsdPlans.ForEach(s => { s.IsAppointmentDelete = false; });//We set to false that don't delete linked shutdown activity in Optimization page
                        if (activity.UnitType == FIFPConstants.UNITTYPE_PIPELINE && activity.UnitName == FIFPConstants.UNITTYPE_MOL)
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => (l.UnitName == FIFPConstants.UNITTYPE_USSC_PLATFORM || (l.UnitType == FIFPConstants.UNITTYPE_PIPELINE && l.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL) && l.IsLinkedShutdownPlan == true)));
                            foreach (FIFPAppointment appointment in activity.LsdPlans)
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                        }
                        else if (activity.UnitType == FIFPConstants.UNITTYPE_PIPELINE && activity.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL)
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => (l.UnitType == FIFPConstants.UNITTYPE_RADIAL && l.IsLinkedShutdownPlan == true)));
                            foreach (FIFPAppointment appointment in activity.LsdPlans.Where(s => s.IsRadialSwitch == false))
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                        }
                        else if (activity.UnitType == FIFPConstants.UNITTYPE_PLATFORM && activity.UnitName == FIFPConstants.UNITTYPE_USSC_PLATFORM)
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => (l.UnitName == FIFPConstants.PLATFORM_ERP_UNIT || l.UnitName == FIFPConstants.PLATFORM_NRP_UNIT || l.UnitName == FIFPConstants.PLATFORM_CSP_UNIT || l.UnitName == FIFPConstants.PLATFORM_CSP_1_UNIT || OccpRadialUnitIds.Any(s => s.Equals(l.UnitID))) && l.IsLinkedShutdownPlan == true));
                            foreach (FIFPAppointment appointment in activity.LsdPlans.Where(s => s.IsRadialSwitch == false))
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                        }
                        else if (activity.UnitType == FIFPConstants.UNITTYPE_PLATFORM && (activity.UnitName == FIFPConstants.PLATFORM_CSP_UNIT || activity.UnitName == FIFPConstants.PLATFORM_CSP_1_UNIT))
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_SEPERATOR && l.IsLinkedShutdownPlan == true));
                            foreach (FIFPAppointment appointment in activity.LsdPlans)
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                        }
                        else if (activity.UnitType == FIFPConstants.UNITTYPE_PLATFORM && activity.UnitName == FIFPConstants.PLATFORM_CP1_UNIT)
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => (l.UnitType == FIFPConstants.UNITTYPE_COMPRESSOR || l.UnitType == FIFPConstants.UNITTYPE_TOWER) && l.IsLinkedShutdownPlan == true));
                            foreach (FIFPAppointment appointment in activity.LsdPlans)
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                        }
                        else if (activity.UnitType == FIFPConstants.UNITTYPE_PLATFORM)
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => (l.UnitType == FIFPConstants.UNITTYPE_RADIAL || l.UnitType == FIFPConstants.UNITTYPE_MODULE) && l.IsLinkedShutdownPlan == true));
                            foreach (FIFPAppointment appointment in activity.LsdPlans)
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                        }
                        else if (activity.UnitType == FIFPConstants.UNITTYPE_RADIAL || activity.UnitType == FIFPConstants.UNITTYPE_TOWER || (activity.UnitType == FIFPConstants.UNITTYPE_TOWER && activity.FluidType == FIFPConstants.FLUIDTYPE_COMBINED) || activity.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_TOWER && l.IsLinkedShutdownPlan == true));
                            foreach (FIFPAppointment appointment in activity.LsdPlans)
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                        }
                        else if (activity.UnitType == FIFPConstants.UNITTYPE_WELL && (activity.ActivityCode == FIFPConstants.ACTIVITY_TYPE_RIG || activity.ActivityCode == FIFPConstants.ACTIVITY_TYPE_RGL))
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_TOWER && l.IsLinkedShutdownPlan == true));
                            foreach (FIFPAppointment appointment in activity.LsdPlans)
                            {
                                appointment.Start = activity.Start; appointment.End = activity.End; appointment.ParentActivityCode = activity.ActivityCode;
                            }
                            Unit wellUnit = UnitList.Where(u => u.UnitName == activity.UnitName && u.UnitType == activity.UnitType).FirstOrDefault();
                            if (wellUnit != null && !LinkedShutdownLocations.Contains(wellUnit) && activity.FilteredLsdPlans.Count > 0)
                            {
                                LinkedShutdownLocations.Add(wellUnit);
                            }
                        }
                        else if (activity.UnitType != FIFPConstants.UNITTYPE_WELL || activity.UnitType != FIFPConstants.UNITTYPE_STRING)
                        {
                            activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>();
                        }
                        Unit unit = UnitList.Where(u => u.UnitName == activity.UnitName && u.UnitType == activity.UnitType).FirstOrDefault();
                        if (unit != null && unit.UnitType != FIFPConstants.UNITTYPE_STRING && unit.UnitType != FIFPConstants.UNITTYPE_WELL && !LinkedShutdownLocations.Contains(unit) && activity.FilteredLsdPlans.Count > 0)
                        {
                            LinkedShutdownLocations.Add(unit);
                        }
                    }
                    if (LinkedShutdownLocations.Count > 0)
                    {
                        //FilteredLSDLocations = new ObservableCollection<Unit>(LinkedShutdownLocations);
                        ServiceLocator.Get<FilterVM>().FilterAppoinements(false);
                    }
                }
            }
            //else
            //{
            //    ServiceLocator.Get<FilterVM>().FilterAppoinements();
            //}

            List<FIFPAppointment> listForScheduleView = new List<FIFPAppointment>();

            if (FilteredLinkedShutdownList != null && FilteredLinkedShutdownList.Count > 0 && SelectedActivity != null && !FilteredLinkedShutdownList.Contains(SelectedActivity))
                listForScheduleView.Add(SelectedActivity);
            listForScheduleView.AddRange(FilteredLinkedShutdownList);
            LoadTimelineView(listForScheduleView);

        }
        #endregion

        #region GetOCCPRadialUnits
        private void GetOCCPRadialUnits()
        {
            OccpRadialUnitIds = UnitList.Where(s => s.UnitName == FIFPConstants.PLATFORM_OCCP_UNIT).SelectMany(p => p.ChildUnitList).Select(m => m.UnitID).ToList<int>();
        }
        #endregion

        public void UndoOptimizationActivities()
        {
            if (ScheduleViewAppointments != null && ScheduleViewAppointments.Count > 0 && ScheduleViewAppointments.Where(s => s.ActivityLevel > 1).Count() > 0)
            {
                foreach (FIFPAppointment appointment in ScheduleViewAppointments.Where(s => s.ActivityLevel > 1))
                {
                    appointment.Start = appointment.ModifiedStart;
                    appointment.End = appointment.ModifiedEnd;
                    ResetUndoActivity(appointment);
                }
                LoadTimelineView(ScheduleViewAppointments);
            }
        }

        private void ResetUndoActivity(FIFPAppointment appointment)
        {
            List<FIFPAppointment> lsdChilds = FilteredLinkedShutdownList.Where(s => s.UnitID == appointment.UnitID && s.IsLinkedShutdownPlan == true).ToList<FIFPAppointment>();
            if (lsdChilds != null && lsdChilds.Count > 0)
            {
                foreach (FIFPAppointment appointmentItem in lsdChilds)
                {
                    bool overlap = !(appointmentItem.End < appointment.Start || appointmentItem.Start > appointment.End);
                    if (overlap)
                    {
                        appointment.OptimizedReason = "Activity optimized";
                        if (!OptimizedActivityList.Contains(appointment))
                            OptimizedActivityList.Add(appointment);
                        break;
                    }
                    else
                    {
                        if (OptimizedActivityList.Contains(appointment))
                        {
                            appointment.OptimizedReason = string.Empty;
                            OptimizedActivityList = new ObservableCollection<FIFPAppointment>(OptimizedActivityList.Except(new List<FIFPAppointment>() { appointment }));
                        }
                    }

                    foreach (FIFPAppointment lsdPlan in appointment.LsdPlans.Where(s => s.IsLinkedShutdownPlan == true))//If we move activity for optimize, we have to change start and end date accordingly.
                    {
                        lsdPlan.Start = appointment.Start;
                        lsdPlan.End = appointment.End;
                    }
                }
            }
        }

        #region LoadTimelineView
        public void LoadTimelineView(List<FIFPAppointment> plans)
        {
            ScheduleViewAppointments = plans;
            AppointmentGroup appointmentGroup = new AppointmentGroup();
            List<ResourceType> lstResources = new List<ResourceType>();
            List<Resource> unitList = new List<Resource>();
            ResourceType unitType = new ResourceType("Unit");
            unitType.DisplayName = "Unit";
            unitType.Name = "Unit";

            foreach (FIFPAppointment appointment in plans)
            {
                Resource resource = new Resource() { ResourceName = appointment.UnitName, DisplayName = appointment.UnitName, ResourceType = unitType.Name };
                if (!unitList.Contains(resource))
                    unitList.Add(resource);
                appointment.Resources.Add(resource);

                if (appointment.PlanID > 0 && !string.IsNullOrEmpty(appointment.FluidType) && !appointment.IsLinkedShutdownPlan)
                {
                    switch (appointment.FluidType)
                    {
                        case FIFPConstants.FLUIDTYPE_OIL:
                            appointment.Category = (appointment.IsAppliedSimops) ? new Category("", new SolidColorBrush(new Color() { R = 0x3D, G = 0x3D, B = 0x3D, A = 0xFF })) : new Category("Oil", new SolidColorBrush(new Color() { R = 0xFF, G = 0x59, B = 0x59, A = 0xFF }));
                            break;
                        case FIFPConstants.FLUIDTYPE_COMBINED:
                            appointment.Category = (appointment.IsAppliedSimops) ? new Category("", new SolidColorBrush(new Color() { R = 0x3D, G = 0x3D, B = 0x3D, A = 0xFF })) : new Category("Combined", new SolidColorBrush(new Color() { R = 0x80, G = 0x0D, B = 0x54, A = 0xFF }));
                            break;
                        case FIFPConstants.FLUIDTYPE_WATER:
                            appointment.Category = (appointment.IsAppliedSimops) ? new Category("", new SolidColorBrush(new Color() { R = 0x3D, G = 0x3D, B = 0x3D, A = 0xFF })) : new Category("Water", new SolidColorBrush(new Color() { R = 0x4B, G = 0xAC, B = 0xC6, A = 0xFF }));
                            break;
                        case FIFPConstants.FLUIDTYPE_GAS:
                            appointment.Category = (appointment.IsAppliedSimops) ? new Category("", new SolidColorBrush(new Color() { R = 0x3D, G = 0x3D, B = 0x3D, A = 0xFF })) : new Category("Gas", new SolidColorBrush(new Color() { R = 0x93, G = 0xA8, B = 0x2A, A = 0xFF }));
                            break;
                        case FIFPConstants.TOWERTYPE_MANIFOLD:
                            appointment.Category = (appointment.IsAppliedSimops) ? new Category("", new SolidColorBrush(new Color() { R = 0x3D, G = 0x3D, B = 0x3D, A = 0xFF })) : new Category("Manifold", new SolidColorBrush(new Color() { R = 0x2E, G = 0x2E, B = 0x2E, A = 0xFF }));
                            break;
                        default:
                            break;
                    }
                }
            }

            appointmentGroup.Appointments = new List<FIFPAppointment>(plans);
            unitType.Resources.AddRange(unitList);
            lstResources.Add(unitType);


            appointmentGroup.ResourceTypes = lstResources;
            appointmentGroup.UnitList = unitList;

            if (OnAppointmentDataCompleted != null)
                OnAppointmentDataCompleted(this, new CustomEventArgs<AppointmentGroup>(appointmentGroup));

        }
        #endregion

        #region ActivityDatagridSelectionChange
        private void ActivityDatagridSelectionChange(DataGrid activityGrid)
        {
            FIFPAppointment activity = (FIFPAppointment)activityGrid.SelectedItem;
            if (activity != null)
            {
                activity.Category = new Category("Oil", new SolidColorBrush(new Color() { R = 0x00, G = 0xFF, B = 0x00, A = 0xFF }));
                SelectedActivity = activity;
            }
        }
        #endregion

        #region Modified datagrid change
        private void ModifiedActivityDatagridSelectionChange(DataGrid activityGrid)
        {
            FIFPAppointment activity = (FIFPAppointment)activityGrid.SelectedItem;
            if (activity != null)
            {
                ModifiedSelectedActivity = activity;
            }
        }

        #endregion

        #region Location datagrid selection changed
        private void LSDLocationGridSelectionChange(DataGrid locationGrid)
        {
            ServiceLocator.Get<FilterVM>().SelectedDivision = ServiceLocator.Get<FilterVM>().DivisionList[0];
            if (locationGrid != null && locationGrid.SelectedItem != null)
            {
                TreeViewGrid.Children.Clear();
                SelectedLSDLocation = locationGrid.SelectedItem as Unit;

                if (SelectedLSDLocation != null)
                {
                    ServiceLocator.Get<FilterVM>().IsDivisionEnabled = true;

                    if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL)//If it is well with RIG activity then we pass the parent tower
                        LoadTreeView(UnitList.Where(p => p.UnitID == SelectedLSDLocation.ParentUnitID).FirstOrDefault());
                    else
                        LoadTreeView(SelectedLSDLocation);

                    ActivityListWithSelectedUnit = (from item in OptimizedPlans
                                                    where item.UnitName == SelectedLSDLocation.UnitName
                                                    select item).ToList<FIFPAppointment>();
                    FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>(ActivityListWithSelectedUnit.OrderBy(s => s.Start));//Activity Datagrid binding

                    List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
                    if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER || SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL)
                    {
                        GenerateOptimizationPlansForTowerandWell();
                    }
                    else
                    {
                        GenerateOptimizationPlansExceptTowerandWell();
                    }
                }
            }
        }

        private void GenerateOptimizationPlansExceptTowerandWell()
        {
            List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
            List<int> linkedSDUnits = new List<int>();
            foreach (FIFPAppointment appointment in ActivityListWithSelectedUnit)
            {
                appointment.IsSelectedLocationActivityLock = true;
                lsdPlans.Add(appointment);
                lsdPlans.AddRange(appointment.FilteredLsdPlans);
                if (linkedSDUnits.Count == 0)
                    linkedSDUnits = appointment.FilteredLsdPlans.Select(s => s.UnitID).ToList<int>();
            }
            if (linkedSDUnits.Count > 0)
            {
                List<FIFPAppointment> activityListForLSDUnits = (from activity in OptimizedPlans
                                                                 where linkedSDUnits.Any(s => s.Equals(activity.UnitID))
                                                                 select activity).ToList<FIFPAppointment>();
                activityListForLSDUnits.ForEach(s => { s.IsSelectedLocationActivityLock = false; });
                OptimizedActivityList = new ObservableCollection<FIFPAppointment>( activityListForLSDUnits.Where(s => s.OptimizedReason == "Activity optimized"));
                lsdPlans.AddRange(activityListForLSDUnits);
            }
            LinkedShutdownList = FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(lsdPlans);
            LoadTimelineView(lsdPlans);
        }

        private void GenerateOptimizationPlansForTowerandWell()
        {
            List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
            List<int> linkedSDUnits = new List<int>();
            List<int> towerChildUnits = new List<int>();
            if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER)
            {
                List<Unit> lstChildUnits = (from item in UnitList
                                            where item.ParentUnitID == SelectedLSDLocation.UnitID
                                            orderby item.UnitType descending
                                            select item).ToList<Unit>();
                towerChildUnits = lstChildUnits.Select(s => s.UnitID).ToList<int>();
            }
            else
            {
                List<Unit> lstChildUnits = (from item in UnitList
                                            where item.ParentUnitID == SelectedLSDLocation.ParentUnitID
                                            orderby item.UnitType descending
                                            select item).ToList<Unit>();
                towerChildUnits = lstChildUnits.Where(m => m.UnitID != SelectedLSDLocation.UnitID).Select(s => s.UnitID).ToList<int>();
            }
            //select activities                                                             
            foreach (FIFPAppointment appointment in ActivityListWithSelectedUnit)
            {
                appointment.IsSelectedLocationActivityLock = true;
                lsdPlans.Add(appointment);//Step 1: Add activity in gantt list
                if (linkedSDUnits.Count == 0)
                {
                    linkedSDUnits.AddRange(towerChildUnits);
                    linkedSDUnits.AddRange(appointment.FilteredLsdPlans.Select(m => m.UnitID));//this holds selected tower child units lsd and linked shutdown unit
                }
            }

            foreach (FIFPAppointment appointment in ActivityListWithSelectedUnit)//LSD Generation
            {
                lsdPlans.AddRange(appointment.LsdPlans.Where(s => towerChildUnits.Any(p => p.Equals(s.UnitID))));
                lsdPlans.AddRange(appointment.FilteredLsdPlans);
            }

            List<FIFPAppointment> filteredLSDPlans = (from activity in OptimizedPlans
                                                      where linkedSDUnits.Any(s => s.Equals(activity.UnitID))
                                                      select activity).ToList<FIFPAppointment>();
            OptimizedActivityList = new ObservableCollection<FIFPAppointment>(filteredLSDPlans.Where(s => s.OptimizedReason == "Activity optimized"));
            filteredLSDPlans.ForEach(s => { s.IsSelectedLocationActivityLock = false; });
            lsdPlans.AddRange(filteredLSDPlans);


            LinkedShutdownList = FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(lsdPlans);
            LoadTimelineView(lsdPlans);
        }
        #endregion

        #region Get filtered lsd locations for selected unit in treeview
        private List<int> GetChildUnitsForSelectedTreeviewUnit(Unit selectedUnit)
        {    
            List<int> lstChildUnits = new List<int>();
            foreach (FIFPAppointment appointment in ActivityListWithSelectedUnit)
            {
                if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PIPELINE && selectedUnit.UnitName == FIFPConstants.UNITTYPE_MOL)
                    lstChildUnits = appointment.LsdPlans.Where(l => l.UnitName == FIFPConstants.UNITTYPE_USSC_PLATFORM || (l.UnitType == FIFPConstants.UNITTYPE_PIPELINE && l.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL) && l.IsLinkedShutdownPlan == true).Select(s => s.UnitID).ToList<int>();
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM && selectedUnit.UnitName == FIFPConstants.UNITTYPE_USSC_PLATFORM)
                {
                    lstChildUnits = appointment.LsdPlans.Where(l => (l.UnitName == FIFPConstants.PLATFORM_ERP_UNIT || l.UnitName == FIFPConstants.PLATFORM_NRP_UNIT || l.UnitName == FIFPConstants.PLATFORM_CSP_UNIT || l.UnitName == FIFPConstants.PLATFORM_CSP_1_UNIT) && l.IsLinkedShutdownPlan == true).Select(s => s.UnitID).ToList<int>();
                    lstChildUnits.AddRange(appointment.LsdPlans.Where(s => OccpRadialUnitIds.Any(l => l.Equals(s.UnitID) && s.IsLinkedShutdownPlan == true)).Select(s => s.UnitID));
                }
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PIPELINE && selectedUnit.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL)
                {
                    List<FIFPAppointment> lst = appointment.LsdPlans.Where(s => s.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL).ToList<FIFPAppointment>();
                    lstChildUnits = appointment.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_RADIAL && l.UnitName == selectedUnit.UnitName && l.IsLinkedShutdownPlan == true).Select(s => s.UnitID).ToList<int>();
                }
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM && (selectedUnit.UnitName == FIFPConstants.PLATFORM_CSP_UNIT || selectedUnit.UnitName == FIFPConstants.PLATFORM_CSP_1_UNIT))
                    lstChildUnits = appointment.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_SEPERATOR && l.IsLinkedShutdownPlan == true).Select(s => s.UnitID).ToList<int>();
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM && selectedUnit.UnitName == FIFPConstants.PLATFORM_CP1_UNIT)
                    lstChildUnits = appointment.LsdPlans.Where(l => (l.UnitType == FIFPConstants.UNITTYPE_COMPRESSOR || l.UnitType == FIFPConstants.UNITTYPE_TOWER) && l.IsLinkedShutdownPlan == true).Select(s => s.UnitID).ToList<int>();
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM)
                    lstChildUnits = appointment.LsdPlans.Where(l => (l.UnitType == FIFPConstants.UNITTYPE_RADIAL || l.UnitType == FIFPConstants.UNITTYPE_MODULE) && l.IsLinkedShutdownPlan == true).Select(s => s.UnitID).ToList<int>();
                else
                    lstChildUnits = appointment.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_TOWER && l.IsLinkedShutdownPlan == true).Select(s => s.UnitID).ToList<int>();

                if (lstChildUnits != null && lstChildUnits.Count > 0)
                    break;
            }
            return lstChildUnits;
        }
        #endregion

        #region Get ChildUnitList

        private void GetTowerChildUnitNameList(List<Unit> lstUnits)
        {
            foreach (Unit unit in lstUnits)
            {
                if (unit.UnitType != FIFPConstants.UNITTYPE_STRING)
                    TowerChildUnitList.Add(unit.UnitID);
                GetTowerChildUnitNameList(UnitList.Where(p => p.ParentUnitID == unit.UnitID).ToList());
            }
        }
        #endregion

        #region LoadTreeviewGrid
        private void LoadTreeviewGrid(Grid grdTreeView)
        {
            TreeViewGrid = grdTreeView;
        }
        #endregion

        #region LoadTreeView
        private void LoadTreeView(Unit selectedUnit)
        {
            if (selectedUnit != null)
            {
                TreeView treeView = new TreeView();
                treeView.Style = Application.Current.Resources["TreeViewStyleSMUR"] as Style;
                treeView.ItemContainerStyle = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                //treeView.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(treeView_SelectedItemChanged);
                
                TreeViewItem rootItem = new TreeViewItem();
                rootItem.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                rootItem.Header = selectedUnit.UnitName;
                rootItem.Tag = selectedUnit;
                rootItem.Foreground = selectedUnit.UnitNameTextColor;
                rootItem.IsExpanded = true;
                rootItem.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                rootItem.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                treeView.Items.Add(rootItem);
                TreeViewGrid.Children.Add(treeView);

                if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PIPELINE && selectedUnit.UnitName == FIFPConstants.UNITTYPE_MOL)
                    GetUnitNameListByMOL(selectedUnit.ChildUnitList, rootItem);
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM && selectedUnit.UnitName == FIFPConstants.UNITTYPE_USSC_PLATFORM)
                    GetUnitNameListByMOL(selectedUnit.ChildUnitList, rootItem);
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM && selectedUnit.UnitName == FIFPConstants.PLATFORM_CP1_UNIT)
                    GetGasUnitNameListByPlatform(selectedUnit.ChildUnitList, rootItem);
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM || selectedUnit.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL)
                    GetUnitNameListByPlatform(selectedUnit.ChildUnitList, rootItem);
                else if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_TOWER || selectedUnit.UnitType == FIFPConstants.UNITTYPE_WELL)
                    GetUnitNameList(new List<Unit>() { selectedUnit }, rootItem, true);
                else
                    GetPipelineUnitNameList(selectedUnit.ChildUnitList, rootItem, selectedUnit.FluidType);//Radial or pipeline
            }
        }
        #endregion

        #region TreeView Collapsed event
        void treeViewItem_Collapsed(object sender, RoutedEventArgs e)
        {
            //Except Tower and well, we have to use filterd lsd locations for expand and collapse
            TreeViewItem item = sender as TreeViewItem;
            if (item != null && item.Tag != null)
            {
                Unit unit = item.Tag as Unit;
                if (unit != null)
                {
                    string unitName = string.Empty;
                    if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL)
                        unitName = UnitList.Where(s => s.UnitID == SelectedLSDLocation.ParentUnitID).FirstOrDefault().UnitName;
                    else
                        unitName = SelectedLSDLocation.UnitName;

                    if (unitName == unit.UnitName && (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER || SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL))
                    {
                        CollapseOptimizationPlansForTowerandWell();

                    }
                    else if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER || unitName == FIFPConstants.PLATFORM_CP1_UNIT)
                    {
                        CollapseOptimizationPlansForTower(unit);
                    }
                    else
                    {
                        CollapseOptimizationPlansForSingleUnit(unit);
                    }
                }
            }
        }

        private void CollapseOptimizationPlansForSingleUnit(Unit unit)
        {
            List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
            List<int> childUnits = UnitList.Where(s => s.ParentUnitID == unit.UnitID).Select(p => p.UnitID).ToList<int>();
            if (unit.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL || unit.UnitName == FIFPConstants.PLATFORM_OCCP_UNIT)
            {
                childUnits = childUnits.Except(OccpRadialUnitIds).ToList<int>();
            }

            List<FIFPAppointment> filteredLSDPlans = (from activity in OptimizedPlans
                                                      where childUnits.Any(s => s.Equals(activity.UnitID))
                                                      select activity).ToList<FIFPAppointment>();
            if (filteredLSDPlans != null && filteredLSDPlans.Count > 0)
            {
                lsdPlans.AddRange(filteredLSDPlans);

                foreach (FIFPAppointment activity in ActivityListWithSelectedUnit)//LSD Generation
                {
                    lsdPlans.AddRange(activity.LsdPlans.Where(s => childUnits.Any(p => p.Equals(s.UnitID))));
                }

                FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(FilteredLinkedShutdownList.Except(lsdPlans));
                LoadTimelineView(new List<FIFPAppointment>(FilteredLinkedShutdownList));
            }
        }

        private void CollapseOptimizationPlansForTower(Unit unit)
        {
            List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
            List<int> towerChildUnits = new List<int>();
            towerChildUnits = UnitList.Where(s => s.ParentUnitID == unit.UnitID).Select(p => p.UnitID).ToList<int>();

            List<FIFPAppointment> filteredLSDPlans = (from activity in OptimizedPlans
                                                      where towerChildUnits.Any(s => s.Equals(activity.UnitID))
                                                      select activity).ToList<FIFPAppointment>();

            if (filteredLSDPlans != null && filteredLSDPlans.Count > 0)
            {
                foreach (FIFPAppointment activity in ActivityListWithSelectedUnit)//LSD Generation
                {
                    lsdPlans.AddRange(activity.LsdPlans.Where(s => towerChildUnits.Any(p => p.Equals(s.UnitID))));
                }

                lsdPlans.AddRange(filteredLSDPlans);

                FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(FilteredLinkedShutdownList.Except(lsdPlans));
                LoadTimelineView(new List<FIFPAppointment>(FilteredLinkedShutdownList));
            }
        }

        private void CollapseOptimizationPlansForTowerandWell()
        {
            List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
            List<int> towerChildUnits = new List<int>();
            List<int> linkedSDUnits = new List<int>();
            if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER)
            {
                towerChildUnits = UnitList.Where(s => s.ParentUnitID == SelectedLSDLocation.UnitID).Select(p => p.UnitID).ToList<int>();
            }
            else
            {
                towerChildUnits = UnitList.Where(s => s.ParentUnitID == SelectedLSDLocation.ParentUnitID && s.UnitID != SelectedLSDLocation.UnitID).Select(p => p.UnitID).ToList<int>();
                //towerChildUnits = lstChildUnits.Where(m => m.UnitID != SelectedLSDLocation.UnitID).Select(s => s.UnitID).ToList<int>();
            }
            //select activities                                                             
            foreach (FIFPAppointment appointment in ActivityListWithSelectedUnit)
            {
                if (linkedSDUnits.Count == 0)
                {
                    linkedSDUnits.AddRange(towerChildUnits);
                    linkedSDUnits.AddRange(appointment.FilteredLsdPlans.Select(m => m.UnitID));//this holds selected tower child units lsd and linked shutdown unit
                }
            }

            foreach (FIFPAppointment appointment in ActivityListWithSelectedUnit)//LSD Generation
            {
                lsdPlans.AddRange(appointment.LsdPlans.Where(s => towerChildUnits.Any(p => p.Equals(s.UnitID))));
            }

            List<FIFPAppointment> filteredLSDPlans = (from activity in OptimizedPlans
                                                      where linkedSDUnits.Any(s => s.Equals(activity.UnitID))
                                                      select activity).ToList<FIFPAppointment>();
            lsdPlans.AddRange(filteredLSDPlans);

            FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(FilteredLinkedShutdownList.Except(lsdPlans));
            LoadTimelineView(new List<FIFPAppointment>(FilteredLinkedShutdownList));
        }
        #endregion

        #region Treeview Expand event
        void treeViewItem_Expanded(object sender, RoutedEventArgs e)
        {
            TreeViewItem item = sender as TreeViewItem;
            if (item != null && item.Tag != null)
            {
                Unit unit = item.Tag as Unit;
                if (unit != null)
                {
                    string unitName = string.Empty;
                    if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL)
                        unitName = UnitList.Where(s => s.UnitID == SelectedLSDLocation.ParentUnitID).FirstOrDefault().UnitName;
                    else
                        unitName = SelectedLSDLocation.UnitName;

                    if (unitName == unit.UnitName && (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER || SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL))
                    {
                        GenerateOptimizationPlansForTowerandWell();
                    }
                    else if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER || unitName == FIFPConstants.PLATFORM_CP1_UNIT)
                    {
                        GenerateOptimizationPlansForTower(unit);
                    }
                    else
                    {
                        GenerateOptimizationPlansForSingleUnit(unit);          
                    }
                }               
            }
        }

        private void GenerateOptimizationPlansForSingleUnit(Unit unit)
        {
            FIFPAppointment appointment = FilteredLinkedShutdownList.Where(s => s.UnitID == unit.UnitID).FirstOrDefault();
            if (appointment != null)
            {
                int index = FilteredLinkedShutdownList.IndexOf(appointment);
                List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
                List<int> childUnits = UnitList.Where(s => s.ParentUnitID == unit.UnitID).Select(p => p.UnitID).ToList<int>();
                if (unit.UnitName == FIFPConstants.UNITTYPE_BYPASS_MOL || unit.UnitName == FIFPConstants.PLATFORM_OCCP_UNIT)
                {
                    childUnits = childUnits.Except(OccpRadialUnitIds).ToList<int>();
                }

                List<FIFPAppointment> filteredLSDPlans = (from activity in OptimizedPlans
                                                          where childUnits.Any(s => s.Equals(activity.UnitID))
                                                          select activity).ToList<FIFPAppointment>();
                if (filteredLSDPlans != null && filteredLSDPlans.Count > 0)
                {
                    filteredLSDPlans.ForEach(s => { s.IsSelectedLocationActivityLock = false; });
                    lsdPlans.AddRange(filteredLSDPlans);

                    foreach (FIFPAppointment activity in ActivityListWithSelectedUnit)//LSD Generation
                    {
                        lsdPlans.AddRange(activity.LsdPlans.Where(s => childUnits.Any(p => p.Equals(s.UnitID))));
                    }

                    List<FIFPAppointment> filterdAppointments = new List<FIFPAppointment>(FilteredLinkedShutdownList);
                    filterdAppointments.InsertRange(index + 1, lsdPlans);
                    FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(filterdAppointments);
                    LoadTimelineView(new List<FIFPAppointment>(FilteredLinkedShutdownList));
                }
            }
        }

        private void GenerateOptimizationPlansForTower(Unit unit)
        {
            FIFPAppointment appointment = FilteredLinkedShutdownList.Where(s => s.UnitID == unit.UnitID).FirstOrDefault();
            if (appointment != null)
            {
                int index = FilteredLinkedShutdownList.IndexOf(appointment);
                List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
                List<int> towerChildUnits = new List<int>();
                towerChildUnits = UnitList.Where(s => s.ParentUnitID == unit.UnitID).Select(p => p.UnitID).ToList<int>();


               
                List<FIFPAppointment> filteredLSDPlans = (from activity in OptimizedPlans
                                                          where towerChildUnits.Any(s => s.Equals(activity.UnitID))
                                                          select activity).ToList<FIFPAppointment>();
                if (filteredLSDPlans != null && filteredLSDPlans.Count > 0)
                {
                    filteredLSDPlans.ForEach(s => { s.IsSelectedLocationActivityLock = false; });
                    lsdPlans.AddRange(filteredLSDPlans);

                    foreach (FIFPAppointment activity in ActivityListWithSelectedUnit)//LSD Generation
                    {
                        lsdPlans.AddRange(activity.LsdPlans.Where(s => towerChildUnits.Any(p => p.Equals(s.UnitID))));
                    }

                    List<FIFPAppointment> filterdAppointments = new List<FIFPAppointment>(FilteredLinkedShutdownList);
                    filterdAppointments.InsertRange(index + 1, lsdPlans);
                    FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(filterdAppointments);
                    LoadTimelineView(new List<FIFPAppointment>(FilteredLinkedShutdownList));
                }
            }
        }
        #endregion

        #region Treeview selection changed
        void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {

        }
        #endregion

        #region GetUnitNameListByTower
        private void GetUnitNameListByTower(List<Unit> lstUnits, Unit rootItem)
        {
            foreach (Unit unit in lstUnits)
            {
                if (unit.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    rootItem.TowerUnitList = UnitList.Where(p => p.ParentUnitID == unit.UnitID).ToList();
                }
                GetUnitNameListByTower(unit.ChildUnitList, rootItem);
            }
        }
        #endregion

        #region FindItemByHeaderRecursive
        // recursively search
        public TreeViewItem FindItemByHeaderRecursive(ItemCollection nodes, string searchFor)
        {
            foreach (TreeViewItem item in nodes)
            {
                if (item.Header.Equals(searchFor))
                    return item;
                if (item.Items.Count > 0)
                {
                    TreeViewItem result =
                    FindItemByHeaderRecursive(item.Items, searchFor);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }
        #endregion

        #region Get Treeview UnitList
        private void GetUnitNameList(List<Unit> lstUnits, TreeViewItem rootItem, bool bInitial)
        {
            foreach (Unit unit in lstUnits)
            {
                if (unit.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    TreeViewItem towerNode = new TreeViewItem();
                    towerNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                    towerNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                    towerNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                    if (bInitial)
                    {
                        TreeViewItem ctItem = FindItemByHeaderRecursive(rootItem.Items, unit.UnitName);
                        if (ctItem != null)
                            IsNodeExists = true;
                        else
                            IsNodeExists = false;
                        if (lstUnits != null && lstUnits[0] != null && lstUnits[0].ChildUnitList != null && lstUnits[0].ChildUnitList.Count > 0)
                        {
                            List<Unit> childUnits = new List<Unit>();
                            if (unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))
                            {
                                if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER && (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_22A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_12A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_40))
                                {
                                    childUnits = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                                }
                                else if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL && ((unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))))
                                {
                                    childUnits = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                                }
                                else
                                {
                                    List<Unit> parentUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).ToList<Unit>();
                                    List<Unit> filterdList = new List<Unit>();
                                    if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_OIL)
                                        filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_OIL || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                                    else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_WATER)
                                        filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_WATER || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                                    else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_GAS)
                                        filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_GAS || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                                    else
                                        filterdList = parentUnitList;

                                    childUnits = filterdList.OrderByDescending(s => s.UnitType).ToList<Unit>();
                                }
                            }
                            else
                                childUnits = lstUnits[0].ChildUnitList.OrderByDescending(s => s.UnitType).ToList<Unit>();
                            foreach (Unit childUnit in childUnits)
                            {
                                if (childUnit.UnitType != FIFPConstants.UNITTYPE_TOWER)
                                {
                                    TreeViewItem node = new TreeViewItem();//Detach expand and collapse event for Well
                                    //node.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                                    //node.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                                    node.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                                    node.Header = childUnit.UnitName;
                                    node.Tag = childUnit;
                                    node.Foreground = childUnit.UnitNameTextColor;
                                    node.IsExpanded = true;
                                    rootItem.Items.Add(node);
                                    if (childUnit.UnitType == FIFPConstants.UNITTYPE_WELL)
                                    {
                                        foreach (Unit stringUnit in childUnit.ChildUnitList)
                                        {
                                            TreeViewItem childNode = new TreeViewItem(); //Detach expand and collapse event for Well
                                            //childNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                                            //childNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                                            childNode.Header = stringUnit.UnitName;
                                            childNode.Tag = stringUnit;
                                            childNode.Foreground = stringUnit.UnitNameTextColor;
                                            childNode.IsExpanded = false;
                                            node.Items.Add(childNode);
                                        }
                                    }
                                }
                            }
                        }
                        bInitial = false;
                    }
                    else
                    {
                        towerNode.Header = unit.UnitName;
                        towerNode.Tag = unit;
                        towerNode.Foreground = unit.UnitNameTextColor;
                        towerNode.IsExpanded = false;

                        TreeViewItem ctItem = FindItemByHeaderRecursive(rootItem.Items, unit.UnitName);
                        if (ctItem != null)
                            IsNodeExists = true;
                        else
                            IsNodeExists = false;
                        if (!IsNodeExists)
                            rootItem.Items.Add(towerNode);
                    }

                    List<Unit> childUnitList = new List<Unit>();
                    if (!IsNodeExists && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))
                    {
                        if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER && (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_22A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_12A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_40))
                        {
                            childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                        }
                        else if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL && ((unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))))
                        {
                            childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                        }
                        else
                        {
                            List<Unit> parentUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).ToList<Unit>();
                            List<Unit> filterdList = new List<Unit>();
                            if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_OIL)
                                filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_OIL || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                            else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_WATER)
                                filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_WATER || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                            else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_GAS)
                                filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_GAS || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                            else
                                filterdList = parentUnitList;

                            childUnitList = filterdList.OrderByDescending(s => s.UnitType).ToList<Unit>();
                        }
                    }
                    else
                        childUnitList = unit.ChildUnitList.OrderByDescending(s => s.UnitType).ToList<Unit>();

                    foreach (Unit childUnit in childUnitList)
                    {
                        TreeViewItem node = new TreeViewItem();//Detach expand and collapse event for Well
                        //node.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                        //node.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                        node.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                        node.Header = childUnit.UnitName;
                        node.Tag = childUnit;
                        node.Foreground = childUnit.UnitNameTextColor;
                        node.IsExpanded = true;
                        if (childUnit.UnitType == FIFPConstants.UNITTYPE_WELL)
                        {
                            foreach (Unit stringUnit in childUnit.ChildUnitList)
                            {
                                TreeViewItem childNode = new TreeViewItem();//Detach expand and collapse event for Well
                                //childNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                                //childNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                                childNode.Header = stringUnit.UnitName;
                                childNode.Tag = stringUnit;
                                childNode.Foreground = stringUnit.UnitNameTextColor;
                                childNode.IsExpanded = false;
                                node.Items.Add(childNode);
                            }
                        }
                        towerNode.Items.Add(node);
                    }
                }
                if (!IsNodeExists && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))
                {
                    //List<Unit> childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).ToList<Unit>();
                    List<Unit> childUnitList = new List<Unit>();
                    if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER && (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_22A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_12A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_40))
                    {
                        childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                    }
                    else if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL && ((unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))))
                    {
                        childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                    }
                    else
                    {
                        List<Unit> parentUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).ToList<Unit>();
                        List<Unit> filterdList = new List<Unit>();
                        if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_OIL)
                            filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_OIL || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                        else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_WATER)
                            filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_WATER || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                        else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_GAS)
                            filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_GAS || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                        else
                            filterdList = parentUnitList;

                        childUnitList = filterdList.OrderByDescending(s => s.UnitType).ToList<Unit>();
                    }
                    GetUnitNameList(childUnitList, rootItem, bInitial);
                }
                else
                    GetUnitNameList(unit.ChildUnitList, rootItem, bInitial);
            }
        }
        #endregion

        #region Get Pipeline radial UnitList
        private void GetPipelineUnitNameList(List<Unit> lstUnits, TreeViewItem rootItem, string fluidType)
        {
            foreach (Unit unit in lstUnits)
            {
                if (unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == fluidType || unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD))
                {
                    TreeViewItem towerNode = new TreeViewItem();
                    towerNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                    towerNode.Header = unit.UnitName;
                    towerNode.Tag = unit;
                    towerNode.Foreground = unit.UnitNameTextColor;
                    towerNode.IsExpanded = false;

                    TreeViewItem ctItem = FindItemByHeaderRecursive(rootItem.Items, unit.UnitName);
                    if (ctItem != null)
                        IsNodeExists = true;
                    else
                        IsNodeExists = false;
                    if (!IsNodeExists)
                        rootItem.Items.Add(towerNode);


                    List<Unit> childUnitList = new List<Unit>();
                    if (!IsNodeExists && (unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40)))
                    {
                        if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER && (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_22A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_12A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_40))
                        {
                            childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                        }
                        else if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL && ((unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))))
                        {
                            childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                        }
                        else
                        {
                            List<Unit> parentUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).ToList<Unit>();
                            List<Unit> filterdList = new List<Unit>();
                            if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_OIL)
                                filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_OIL || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                            else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_WATER)
                                filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_WATER || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                            else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_GAS)
                                filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_GAS || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                            else
                                filterdList = parentUnitList;

                            childUnitList = filterdList.OrderByDescending(s => s.UnitType).ToList<Unit>();
                        }
                    }
                    else
                        childUnitList = unit.ChildUnitList.OrderByDescending(s => s.UnitType).ToList<Unit>();

                    foreach (Unit childUnit in childUnitList)
                    {
                        if (childUnit.FluidType == fluidType)
                        {
                            TreeViewItem node = new TreeViewItem();
                            node.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                            node.Header = childUnit.UnitName;
                            node.Tag = childUnit;
                            node.Foreground = childUnit.UnitNameTextColor;
                            node.IsExpanded = false;
                            if (childUnit.UnitType == FIFPConstants.UNITTYPE_WELL)
                            {
                                foreach (Unit stringUnit in childUnit.ChildUnitList)
                                {
                                    TreeViewItem childNode = new TreeViewItem();
                                    childNode.Header = stringUnit.UnitName;
                                    childNode.Tag = stringUnit;
                                    childNode.Foreground = stringUnit.UnitNameTextColor;
                                    childNode.IsExpanded = false;
                                    node.Items.Add(childNode);
                                }
                            }
                            towerNode.Items.Add(node);
                        }
                    }
                }
                if (!IsNodeExists && (unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40)))
                {
                    //List<Unit> childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).ToList<Unit>();
                    List<Unit> childUnitList = new List<Unit>();
                    if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER && (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_22A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_12A || SelectedLSDLocation.UnitName == FIFPConstants.TOWER_UT_40))
                    {
                        childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                    }
                    else if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL && ((unit.UnitType == FIFPConstants.UNITTYPE_TOWER && (unit.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || unit.UnitName == FIFPConstants.TOWER_UT_22A || unit.UnitName == FIFPConstants.TOWER_UT_12A || unit.UnitName == FIFPConstants.TOWER_UT_40))))
                    {
                        childUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).OrderByDescending(s => s.UnitType).ToList<Unit>();
                    }
                    else
                    {
                        List<Unit> parentUnitList = UnitList.Where(s => s.UnitName == unit.UnitName).SelectMany(p => p.ChildUnitList).ToList<Unit>();
                        List<Unit> filterdList = new List<Unit>();
                        if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_OIL)
                            filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_OIL || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                        else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_WATER)
                            filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_WATER || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                        else if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_GAS)
                            filterdList = parentUnitList.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_GAS || s.FluidType == FIFPConstants.FLUIDTYPE_COMBINED || s.FluidType == FIFPConstants.TOWERTYPE_MANIFOLD).ToList<Unit>();
                        else
                            filterdList = parentUnitList;

                        childUnitList = filterdList.OrderByDescending(s => s.UnitType).ToList<Unit>();
                    }

                    GetPipelineUnitNameList(childUnitList, rootItem, fluidType);
                }
                else
                    GetPipelineUnitNameList(unit.ChildUnitList, rootItem, fluidType);
            }
        }
        #endregion

        #region GetUnitNameListByMOL
        private void GetUnitNameListByMOL(List<Unit> lstUnits, TreeViewItem rootItem)
        {
            foreach (Unit unit in lstUnits)
            {
                TreeViewItem usscNode = new TreeViewItem();
                usscNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                if (unit.UnitType == FIFPConstants.UNITTYPE_PLATFORM || unit.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
                {
                    usscNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                    usscNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                    usscNode.Header = unit.UnitName;
                    usscNode.Tag = unit;
                    usscNode.Foreground = unit.UnitNameTextColor;
                    usscNode.IsExpanded = false;
                    rootItem.Items.Add(usscNode);

                    foreach (Unit platformUnit in unit.ChildUnitList)
                    {
                        TreeViewItem platformNode = new TreeViewItem();
                        platformNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                        if (platformUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM || platformUnit.UnitType == FIFPConstants.UNITTYPE_SEPERATOR || platformUnit.UnitType == FIFPConstants.UNITTYPE_RADIAL)
                        {
                            platformNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                            platformNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                            platformNode.Header = platformUnit.UnitName;
                            platformNode.Tag = platformUnit;
                            platformNode.Foreground = platformUnit.UnitNameTextColor;
                            platformNode.IsExpanded = false;
                            usscNode.Items.Add(platformNode);

                            foreach (Unit childUnit in platformUnit.ChildUnitList)
                            {
                                TreeViewItem radialNode = new TreeViewItem();
                                radialNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                                if (childUnit.UnitType == FIFPConstants.UNITTYPE_RADIAL)
                                {
                                    radialNode.Header = childUnit.UnitName;
                                    radialNode.Tag = childUnit;
                                    radialNode.Foreground = childUnit.UnitNameTextColor;
                                    radialNode.IsExpanded = false;
                                    platformNode.Items.Add(radialNode);
                                }
                                else if (childUnit.UnitType == FIFPConstants.UNITTYPE_SEPERATOR)
                                {
                                    radialNode.Header = childUnit.UnitName;
                                    radialNode.Tag = childUnit;
                                    radialNode.Foreground = childUnit.UnitNameTextColor;
                                    radialNode.IsExpanded = false;
                                    platformNode.Items.Add(radialNode);
                                }
                                //GetTowerUnitNameList(radialUnit.ChildUnitList, radialNode);
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region GetUnitNameListByUSSC
        private void GetUnitNameListByUSOSSP(List<Unit> lstUnits, TreeViewItem rootItem)
        {
            foreach (Unit unit in lstUnits)
            {
                TreeViewItem usscNode = new TreeViewItem();
                usscNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                usscNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                usscNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                usscNode.Header = unit.UnitName;
                usscNode.Tag = unit;
                usscNode.Foreground = unit.UnitNameTextColor;
                usscNode.IsExpanded = false;
                rootItem.Items.Add(usscNode);

                foreach (Unit platformUnit in unit.ChildUnitList)
                {
                    TreeViewItem platformNode = new TreeViewItem();
                    platformNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                    if (platformUnit.UnitType == FIFPConstants.UNITTYPE_PLATFORM)
                    {
                        platformNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                        platformNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                        platformNode.Header = platformUnit.UnitName;
                        platformNode.Tag = platformUnit;
                        platformNode.Foreground = platformUnit.UnitNameTextColor;
                        platformNode.IsExpanded = false;
                        usscNode.Items.Add(platformNode);

                        foreach (Unit radialUnit in platformUnit.ChildUnitList)
                        {
                            TreeViewItem radialNode = new TreeViewItem();
                            radialNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                            if (radialUnit.UnitType == FIFPConstants.UNITTYPE_RADIAL)
                            {
                                radialNode.Header = radialUnit.UnitName;
                                radialNode.Tag = radialUnit;
                                radialNode.Foreground = radialUnit.UnitNameTextColor;
                                radialNode.IsExpanded = false;
                                platformNode.Items.Add(radialNode);
                            }
                            //GetTowerUnitNameList(radialUnit.ChildUnitList, radialNode);
                        }
                    }
                }
            }
        }
        #endregion

        #region GetUnitNameListByPlatform
        private void GetUnitNameListByPlatform(List<Unit> lstUnits, TreeViewItem rootItem)
        {
            foreach (Unit unit in lstUnits)
            {
                TreeViewItem radialNode = new TreeViewItem();
                radialNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                if (unit.UnitType == FIFPConstants.UNITTYPE_RADIAL)
                {
                    radialNode.Header = unit.UnitName;
                    radialNode.Tag = unit;
                    radialNode.Foreground = unit.UnitNameTextColor;
                    radialNode.IsExpanded = false;
                    rootItem.Items.Add(radialNode);
                }
                else if (unit.UnitType == FIFPConstants.UNITTYPE_SEPERATOR)
                {
                    radialNode.Header = unit.UnitName;
                    radialNode.Tag = unit;
                    radialNode.Foreground = unit.UnitNameTextColor;
                    radialNode.IsExpanded = false;
                    rootItem.Items.Add(radialNode);
                }
                else if (unit.UnitType == FIFPConstants.UNITTYPE_MODULE)
                {
                    radialNode.Header = unit.UnitName;
                    radialNode.Tag = unit;
                    radialNode.Foreground = unit.UnitNameTextColor;
                    radialNode.IsExpanded = false;
                    rootItem.Items.Add(radialNode);
                }
                //GetTowerUnitNameList(unit.ChildUnitList, radialNode);
            }
        }
        #endregion

        #region GetGasUnitNameListByPlatform
        private void GetGasUnitNameListByPlatform(List<Unit> lstUnits, TreeViewItem rootItem)
        {
            foreach (Unit unit in lstUnits)
            {
                TreeViewItem radialNode = new TreeViewItem();
                radialNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                if (unit.UnitType == FIFPConstants.UNITTYPE_RADIAL)
                {
                    //radialNode.Header = unit.UnitName;
                    //radialNode.Tag = unit;
                    //radialNode.Foreground = unit.UnitNameTextColor;
                    //radialNode.IsExpanded = false;
                    //rootItem.Items.Add(radialNode);
                    foreach (Unit towerUnit in unit.ChildUnitList)
                    {
                        TreeViewItem towerNode = new TreeViewItem();
                        towerNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                        towerNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                        towerNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                        towerNode.Header = towerUnit.UnitName;
                        towerNode.Tag = towerUnit;
                        towerNode.Foreground = towerUnit.UnitNameTextColor;
                        towerNode.IsExpanded = false;
                        rootItem.Items.Add(towerNode);
                        foreach (Unit wellUnit in towerUnit.ChildUnitList)
                        {
                            TreeViewItem childNode = new TreeViewItem();
                            childNode.Header = wellUnit.UnitName;
                            childNode.Tag = wellUnit;
                            childNode.Foreground = wellUnit.UnitNameTextColor;
                            childNode.IsExpanded = false;
                            towerNode.Items.Add(childNode);
                        }
                    }
                }
                else if (unit.UnitType == FIFPConstants.UNITTYPE_COMPRESSOR)
                {
                    radialNode.Header = unit.UnitName;
                    radialNode.Tag = unit;
                    radialNode.Foreground = unit.UnitNameTextColor;
                    radialNode.IsExpanded = false;
                    rootItem.Items.Add(radialNode);
                }
                //GetTowerUnitNameList(unit.ChildUnitList, radialNode);
            }
        }
        #endregion

        #region Get GetTowerUnitNameList
        private void GetTowerUnitNameList(List<Unit> lstUnits, TreeViewItem rootItem)
        {
            foreach (Unit unit in lstUnits)
            {
                if (unit.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    TreeViewItem towerNode = new TreeViewItem();
                    towerNode.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                    towerNode.Expanded += new RoutedEventHandler(treeViewItem_Expanded);
                    towerNode.Collapsed += new RoutedEventHandler(treeViewItem_Collapsed);
                    towerNode.Header = unit.UnitName;
                    towerNode.Tag = unit;
                    towerNode.Foreground = unit.UnitNameTextColor;
                    towerNode.IsExpanded = false;
                    rootItem.Items.Add(towerNode);

                    foreach (Unit childUnit in unit.ChildUnitList)
                    {
                        TreeViewItem node = new TreeViewItem();
                        node.Style = Application.Current.Resources["TreeViewItemStyle1"] as Style;
                        node.Header = childUnit.UnitName;
                        node.Tag = childUnit;
                        node.Foreground = childUnit.UnitNameTextColor;
                        node.IsExpanded = false;
                        if (childUnit.UnitType == FIFPConstants.UNITTYPE_WELL)
                        {
                            foreach (Unit stringUnit in childUnit.ChildUnitList)
                            {
                                TreeViewItem childNode = new TreeViewItem();
                                childNode.Header = stringUnit.UnitName;
                                childNode.Tag = stringUnit;
                                childNode.Foreground = stringUnit.UnitNameTextColor;
                                childNode.IsExpanded = false;
                                node.Items.Add(childNode);
                            }
                        }
                        towerNode.Items.Add(node);
                    }
                }
                GetTowerUnitNameList(unit.ChildUnitList, rootItem);
            }
        }
        #endregion

        #region Commented block


        //if (TowerChildUnitList.Count > 0)
        //    TowerChildUnitList.Clear();
        //GetTowerChildUnitNameList(UnitList.Where(s => s.ParentUnitID == SelectedLSDLocation.UnitID).ToList<Unit>());

        //lsdPlans.AddRange(from activity in OptimizedPlans //Step 1: Add selected tower child units in gantt list
        //                  where TowerChildUnitList.Any(s => s.Equals(activity.UnitID))
        //                  select activity);

        //foreach (FIFPAppointment appoinment in ActivityListWithSelectedUnit)//Step 1: Add selected tower child units linked shutdowns in gantt list
        //{
        //    lsdPlans.AddRange(appoinment.LsdPlans.Where(s => TowerChildUnitList.Any(p => p.Equals(s.UnitID))));
        //}
        #endregion
    }
}
